home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Internet Surfer: Getting Started
/
Internet Surfer - Getting Started (Wayzata Technology)(7231)(1995).bin
/
pc
/
mac
/
bonus
/
peter_le
/
finger-1
/
my_units
/
myoomain.p
< prev
next >
Wrap
Text File
|
1992-02-24
|
20KB
|
780 lines
unit OOMainLoop;
{ This code is part of the Finger/Fingerd source code, written in THINK Pascal 4 }
{ Copyright 1991-1992 Peter N Lewis }
{ If you use this code, you must give me credit in your about box and documentation }
{ This is part of my generic library of routines }
interface
const
WT_NotMine = 'NtMe';
WT_Generic = 'Genr';
type
SCType = (SCSave, SCCancel, SCDiscard);
WObject = object
window: dialogPtr;
window_type: OSType;
growRect: rect; { minimum/maximum rect size (for use with grow window) }
zoomSize: point; { Optimum zoom size }
procedure Create (id: integer);
procedure Destroy;
function SaveChanges: SCType;
procedure DoClose;
{ DoClose checks modified things etc, then calls Destroy }
function SetMenuBar: boolean;
function EditMenuEnabled: boolean;
procedure SetEditMenuItem (item: integer);
procedure DoEditMenu (item: integer);
function DoMenuKey (er: eventRecord; ch: char): longInt;
procedure CalculateRegion (var rgn: rgnHandle);
function WaitForEvent (var er: eventRecord; sleep: longInt): boolean;
procedure DoIdle;
procedure DoDiskEvent (message: longInt);
procedure DoSuspendResume (resume: boolean);
procedure DoHighLevel (er: eventRecord);
procedure DoContent (where: point);
procedure DoKey (modifiers: integer; ch: char; code: integer);
procedure DoSpecialKey (modifiers: integer; ch: char; code: integer);
procedure DoAutoKey (modifiers: integer; ch: char; code: integer);
procedure DoDrag (where: point);
procedure DoGrow (where: point);
procedure Zoom (code: integer);
procedure DoZoom (where: point; code: integer);
procedure DoGoAway (where: point);
procedure DoUpdate;
procedure DoMouseMoved (where: point);
procedure DoActivateDeactivate (activate: boolean);
procedure Resize;
procedure Draw;
function DoMainClick (er: eventRecord): boolean;
function DoIsDialogEvent (er: eventRecord): boolean;
function DoDialogSelect (er: eventRecord; var dlg: dialogPtr; var item: integer): boolean;
function HandleEvents (er: eventRecord): boolean;
end;
DObject = object(WObject)
ok_item, cancel_item: integer;
procedure Create (id: integer);
override;
procedure Destroy;
override;
function HandleEvents (er: eventRecord): boolean;
override;
procedure DoItem (item: integer);
procedure DoItemWhere (er: eventRecord; item: integer);
procedure DoCancel (modifiers: integer; ch: char; code: integer);
procedure DoOK (modifiers: integer; ch: char; code: integer);
end;
DTObject = object(DObject)
procedure SetEditMenuItem (item: integer);
override;
function EditMenuEnabled: boolean;
override;
procedure DoEditMenu (item: integer);
override;
function DoIsDialogEvent (er: eventRecord): boolean;
override;
end;
var
default_object: WObject;
function GetWType (wp: windowPtr): OSType;
function GetWObject (wp: windowPtr): WObject;
function GetDObject (dlg: dialogPtr): DObject;
function FrontObject: WObject;
function IsWObjectFront (o: WObject): boolean;
procedure InitMainLoop (dobj: DObject; domenu: procptr);
{ dobj will be used returned with window set to wp whenever GetWObject/GetDObject is called with a DA or nil window }
procedure FinishMainLoop;
{ procedure DoMenu (themenu, theitem: integer);}
implementation
uses
Script, MyUtils, MyUtilities, MyTypes, MyFMenus, BaseGlobals, MyTEUtils;
type
WStateDataPtr = ^WStateData;
WStateDataHandle = ^WStateDataPtr;
const
{ from EPPC }
kHighLevelEvent = 23;
OOMagic = 'MyOO';
type
myWindowRecord = record
thewindow: windowRecord;
magic: OSType;
end;
myWindowPtr = ^myWindowRecord;
myDialogRecord = record
thedialog: dialogRecord;
magic: OSType;
end;
myDialogPtr = ^myDialogRecord;
{ from AppleEvents }
function AEProcessAppleEvent (theEventRecord: EventRecord): OSErr;
inline
$303C, $021B, $A816;
var
domenup: procptr;
procedure DoMenu (themenu, theitem: integer; domenu: procptr);
inline
$205F, $4E90;
{$S Init}
procedure InitMainLoop (dobj: DObject; domenu: procptr);
var
i: integer;
dummy: boolean;
dummy_er: eventRecord;
begin
for i := 1 to 5 do
dummy := EventAvail(everyEvent, dummy_er);
domenup := domenu;
default_object := dobj;
end;
{$S Term}
procedure FinishMainLoop;
begin
dispose(default_object);
end;
{$S}
function GetWRC (wp: windowPtr): WObject;
var
rc: longInt;
begin
if wp = nil then
rc := 0
else if windowPeek(wp)^.windowKind < 0 then
rc := 0
else if windowPeek(wp)^.windowKind = dialogKind then
if myDialogPtr(wp)^.magic = OOMagic then
rc := GetWRefCon(wp)
else
rc := 0
else if myWindowPtr(wp)^.magic = OOMagic then
rc := GetWRefCon(wp)
else
rc := 0;
if rc = 0 then begin
default_object.window := wp;
rc := longInt(default_object);
end;
GetWRC := WObject(rc);
end;
function GetWType (wp: windowPtr): OSType;
var
wo: WObject;
begin
wo := GetWRC(wp);
if wo = default_object then
GetWType := WT_NotMine
else
GetWType := wo.window_type;
end;
function GetWObject (wp: windowPtr): WObject;
begin
GetWObject := GetWRC(wp);
end;
function GetDObject (dlg: dialogPtr): DObject;
begin
GetDObject := DObject(GetWRC(dlg));
end;
function FrontObject: WObject;
begin
FrontObject := GetWRC(FrontWindow);
end;
function IsWObjectFront (o: WObject): boolean;
begin
if o = nil then
IsWObjectFront := false
else if o.window = nil then
IsWObjectFront := false
else
IsWObjectFront := o.window = FrontWindow;
end;
function WObject.SaveChanges: SCType;
var
a: integer;
title: str255;
begin
SelectWindow(window);
GetWTitle(window, title);
if quitNow then
ParamText(title, GetGlobalString(quiting_str), '', '')
else
ParamText(title, GetGlobalString(closing_str), '', '');
SetCursor(arrow);
a := Alert(save_changes_alert_id, nil);
SaveChanges := SCType(a - 1);
end;
function WObject.EditMenuEnabled: boolean;
begin
if window = nil then
EditMenuEnabled := false
else
EditMenuEnabled := windowPeek(window)^.windowKind < 0
end;
function WObject.SetMenuBar: boolean;
var
oldEditEnabled, editEnabled: boolean;
begin
oldEditEnabled := GetIDItemEnable(M_Edit, 0);
editEnabled := FrontObject.EditMenuEnabled;
if editEnabled <> oldEditEnabled then
SetIDItemEnable(M_Edit, 0, editEnabled);
SetMenuBar := editEnabled <> oldEditEnabled;
end;
procedure WObject.SetEditMenuItem (item: integer);
begin
end;
procedure WObject.DoEditMenu (item: integer);
var
dummyb: boolean;
begin
if item <= 6 then
dummyb := SystemEdit(item - 1);
end;
function WObject.DoMenuKey (er: eventRecord; ch: char): longInt;
const
kMaskVirtualKey = $0000FF00; {get virtual key from event message}
kMaskASCII1 = $00FF0000;
kMaskASCII2 = $000000FF; {get key from KeyTrans return}
kKeyUpMask = $0080;
var
h: handle;
virtualKey, keyCId, state, keyInfo: longInt;
keycode: integer;
lowchar, highchar: integer;
begin
if BAND(er.modifiers, optionKey) <> 0 then begin
virtualKey := BSR(BAND(er.message, kMaskVirtualKey), 8);
keyCode := BOR(BOR(BXOR(er.modifiers, optionKey), kKeyUpMask), virtualKey);
state := 0;
keyCId := GetScript(GetEnvirons(smKeyScript), smScriptKeys);
h := GetResource('KCHR', keyCId);
if h <> nil then begin
{ we don't need to lock the resource since KeyTrans}
{ will not move memory }
keyInfo := KeyTrans(h^, keyCode, state);
ReleaseResource(h);
LowChar := BAND(keyInfo, $FF);
HighChar := BAND(BSR(keyInfo, 16), $FF);
if lowChar <> 0 then
ch := chr(lowChar);
if highChar <> 0 then
ch := chr(highChar);
end;
end;
DoMenuKey := MenuKey(ch);
end;
procedure WObject.CalculateRegion (var rgn: rgnHandle);
begin
rgn := nil;
end;
function WObject.WaitForEvent (var er: eventRecord; sleep: longInt): boolean;
var
rgn: rgnHandle;
b: boolean;
begin
CalculateRegion(rgn);
WaitForEvent := WaitGetNextEvent(everyEvent, er, sleep, rgn);
if rgn <> nil then
DisposeRgn(rgn);
end;
procedure WObject.DoDiskEvent (message: longInt);
var
pt: point;
oe: OSErr;
begin
if (HiWord(message) <> noErr) then begin
pt.h := ((screenbits.bounds.Right - screenbits.bounds.Left - 304) div 2);
pt.v := ((screenbits.bounds.Bottom - screenbits.bounds.Top - 156) div 3);
InitCursor;
oe := DIBadMount(pt, message);
end;
end;
procedure WObject.DoSuspendResume (resume: boolean);
begin
in_foreground := resume;
FrontObject.DoActivateDeactivate(resume);
InitCursor;
end;
procedure WObject.DoHighLevel (er: eventRecord);
var
oe: OSErr;
begin
if has_AppleEvents then
oe := AEProcessAppleEvent(er);
end;
procedure JointCreate (o: WObject);
begin
SetWRefCon(o.window, longInt(o));
o.growRect := GetGrayRgn^^.rgnBBox;
o.growRect.left := 61;
o.growRect.top := 61;
o.zoomSize.h := 30000;
o.zoomSize.v := 30000;
o.window_type := WT_Generic;
end;
procedure WObject.Create (id: integer);
var
wp: myWindowPtr;
begin
wp := myWindowPtr(NewPtr(SizeOf(myWindowRecord)));
wp^.magic := OOMagic;
window := GetNewWindow(id, ptr(wp), POINTER(-1));
JointCreate(self);
end;
procedure WObject.Destroy;
begin
if window <> nil then
DisposeWindow(window);
if self <> default_object then
dispose(self);
end;
procedure WObject.DoClose;
begin
Destroy;
end;
procedure WObject.DoContent (where: point);
begin
end;
procedure WObject.DoKey (modifiers: integer; ch: char; code: integer);
begin
SysBeep(1);
end;
procedure WObject.DoSpecialKey (modifiers: integer; ch: char; code: integer);
var
item: integer;
begin
case code of
undoKey:
item := EMundo;
cutKey:
item := EMcut;
copyKey:
item := EMcopy;
pasteKey:
item := EMpaste;
clearKey:
item := EMclear;
otherwise
item := -1;
end;
if item <> -1 then begin
SetFMenus;
if not GetIDItemEnable(M_Edit, 0) or not GetIDItemEnable(M_Edit, item) then
item := -1;
end;
if item = -1 then
DoKey(modifiers, ch, code)
else
DoMenu(M_Edit, item, domenup);
end;
procedure WObject.DoAutoKey (modifiers: integer; ch: char; code: integer);
begin
end;
procedure WObject.DoDrag (where: point);
var
temprect: rect;
bnds1, bnds2: point;
begin
tempRect := GetGrayRgn^^.rgnBBox;
bnds1 := window^.portBits.bounds.topleft;
DragWindow(window, where, tempRect);
bnds2 := window^.portBits.bounds.topleft;
OffsetRect(WStateDataHandle(WindowPeek(window)^.dataHandle)^^.stdState, bnds1.h - bnds2.h, bnds1.v - bnds2.v);
{ OffsetRect(WStateDataHandle(WindowPeek(window)^.dataHandle)^^.userState, bnds1.h - bnds2.h, bnds1.v - bnds2.v);}
end;
procedure WObject.DoGrow (where: point);
var
mypt: point;
oldrect: rect;
mResult: longInt;
tempRect: rect;
begin
SetPort(window);
myPt := where;
GlobalToLocal(myPt);
oldrect := window^.portRect;
mResult := GrowWindow(window, where, growRect);
SizeWindow(window, LoWord(mResult), HiWord(mResult), TRUE);
SetRect(tempRect, 0, myPt.v - 15, myPt.h + 15, myPt.v + 15);
EraseRect(tempRect);
InvalRect(tempRect);
SetRect(tempRect, myPt.h - 15, 0, myPt.h + 15, myPt.v + 15);
EraseRect(tempRect);
InvalRect(tempRect);
Resize;
end;
procedure WObject.Zoom (code: integer);
var
globalPortRect, theSect, zoomRect: Rect;
nthDevice, dominantGDevice: GDHandle;
sectFlag: boolean;
bias: integer;
greatestArea, sectArea: longInt;
tl, br: point;
begin
SetPort(window);
EraseRect(window^.portRect); {recommended for cosmetic reasons}
if (code = inZoomOut) then begin
if sysenv.hasColorQD then begin
globalPortRect := window^.portRect;
LocalToGlobal(globalPortRect.topLeft);
LocalToGlobal(globalPortRect.botRight);
{ must calculate height of window's title bar }
{ bias := globalPortRect.top - 1 - WindowPeek(window)^.strucRgn^^.rgnBBox.top; }
{ This doesn't work if the window is invisible, because structRgn is empty, and thus rgnBBox is 0,0,0,0 }
bias := 18;
nthDevice := GetDeviceList;
greatestArea := -1;
{ This loop checks the window against all the gdRects in the }
{ gDevice list and remembers which gdRect contains the largest }
{ portion of the window being zoomed. }
while nthDevice <> nil do begin
sectFlag := SectRect(globalPortRect, nthDevice^^.gdRect, theSect);
with theSect do
sectArea := LONGINT(right - left) * (bottom - top);
if sectArea > greatestArea then begin
greatestArea := sectArea;
dominantGDevice := nthDevice;
end;
nthDevice := GetNextDevice(nthDevice);
end; {of WHILE}
{ We must create a zoom rectangle manually in this case. }
{ account for menu bar height as well, if on main device }
if dominantGDevice = GetMainDevice then
bias := bias + GetMBarHeight;
with dominantGDevice^^.gdRect do
SetRect(zoomRect, left + 3, top + bias + 3, right - 3, bottom - 3);
end {of Color QuickDraw conditional stuff}
else begin
zoomRect := WStateDataHandle(WindowPeek(window)^.dataHandle)^^.stdState;
end;
tl := window^.portRect.topleft;
LocalToGlobal(tl);
br.v := tl.v + zoomSize.v;
br.h := tl.h + zoomSize.h;
with zoomRect do begin
if PtInRect(tl, zoomRect) and PtInRect(br, zoomRect) then begin
zoomRect.topleft := tl;
zoomRect.botright := br;
end
else begin
if right - left > zoomSize.h then
right := left + zoomSize.h;
if bottom - top > zoomSize.v then
bottom := top + zoomSize.v;
end;
end;
{ Set up the WStateData record for this window. }
WStateDataHandle(WindowPeek(window)^.dataHandle)^^.stdState := zoomRect;
end;
ZoomWindow(window, code, true);
Resize;
end;
procedure WObject.DoZoom (where: point; code: integer);
begin
SetPort(window);
if TrackBox(window, where, code) then
Zoom(code);
end;
procedure WObject.DoGoAway (where: point);
begin
if TrackGoAway(window, where) then
DoClose;
end;
procedure WObject.DoUpdate;
begin
BeginUpdate(window);
Draw;
EndUpdate(window);
end;
procedure WObject.DoMouseMoved (where: point);
begin
end;
procedure WObject.DoActivateDeactivate (activate: boolean);
begin
if activate then
SelectWindow(window);
end;
procedure WObject.Resize;
begin
end;
procedure WObject.Draw;
begin
end;
function WObject.DoIsDialogEvent (er: eventRecord): boolean;
begin
DoIsDialogEvent := IsDialogEvent(er);
end;
function WObject.DoDialogSelect (er: eventRecord; var dlg: dialogPtr; var item: integer): boolean;
begin
DoDialogSelect := DialogSelect(er, dlg, item);
end;
procedure WObject.DoIdle;
begin
end;
function WObject.DoMainClick (er: eventRecord): boolean;
var
b: boolean;
wp: windowPtr;
mResult: longInt;
code: integer;
begin
b := false;
code := FindWindow(er.where, wp);
if (wp <> nil) and (wp <> window) then begin
if (BAND(er.modifiers, cmdKey) = 0) or (code <> inDrag) then
SelectWindow(wp);
if code = inDrag then
GetWObject(wp).DoDrag(er.where);
end
else
case code of
inMenuBar: begin
SetFMenus;
mResult := MenuSelect(er.where);
if mResult <> 0 then
DoMenu(HiWord(mResult), LoWord(mResult), domenup);
end;
InDrag:
DoDrag(er.where);
inGrow:
DoGrow(er.where);
inZoomIn, inZoomOut:
DoZoom(er.where, code);
inGoAway:
DoGoAway(er.where);
inContent: begin
GlobalToLocal(er.where);
DoContent(er.where);
end;
inSysWindow:
SystemClick(er, window);
otherwise
b := true;
end;
DoMainClick := b;
end;
function WObject.HandleEvents (er: eventRecord): boolean;
var
wp: windowPtr;
b: boolean;
obj: WObject;
code: integer;
mResult: longInt;
myPt: point;
temprect: rect;
ch: char;
dlg: dialogPtr;
item: integer;
begin
DoIdle;
b := true;
if DoIsDialogEvent(er) then begin
if DoDialogSelect(er, dlg, item) then begin
GetDObject(dlg).DoItemWhere(er, item);
b := false;
end;
end;
if b then begin
b := false;
case er.what of
MouseDown:
b := DoMainClick(er);
KeyDown: begin
ch := chr(BAND(er.message, CharCodeMask));
mResult := 0;
if BAND(er.modifiers, CmdKey) <> 0 then begin
SetFMenus;
mResult := DoMenuKey(er, ch);
end;
if mResult <> 0 then
DoMenu(HiWord(mResult), LoWord(mResult), domenup)
else
DoSpecialKey(er.modifiers, ch, BAND(er.message, keyCodeMask) div $100);
end;
AutoKey:
DoAutoKey(er.modifiers, chr(BAND(er.message, CharCodeMask)), BAND(er.message, keyCodeMask) div $100);
UpdateEvt:
GetWObject(windowPtr(er.message)).DoUpdate;
ActivateEvt:
GetWObject(windowPtr(er.message)).DoActivateDeactivate(odd(er.modifiers));
kOSEvent:
if BAND(BROTL(er.message, 8), $FF) = kSuspendResumeMessage then
DoSuspendResume(BAnd(er.message, kResumeMask) <> 0)
else if BAND(BROTL(er.message, 8), $FF) = kMouseMovedMessage then
DoMouseMoved(er.where)
else
b := true;
kHighLevelEvent:
DoHighLevel(er);
DiskEvt:
DoDiskEvent(er.message);
otherwise
b := true;
end;
end;
HandleEvents := b;
end;
procedure DObject.Create (id: integer);
var
wp: myDialogPtr;
begin
wp := myDialogPtr(NewPtr(SizeOf(myDialogRecord)));
wp^.magic := OOMagic;
window := GetNewDialog(id, ptr(wp), POINTER(-1));
ok_item := 0;
cancel_item := 0;
JointCreate(self);
end;
procedure DObject.Destroy;
begin
if window <> nil then
DisposDialog(window);
if self <> default_object then
dispose(self);
end;
procedure DObject.DoOK (modifiers: integer; ch: char; code: integer);
begin
if ok_item = 0 then
DoKey(modifiers, ch, code)
else begin
if ControlEnabled(window, ok_item) then begin
FlashItem(window, ok_Item);
DoItem(ok_item);
end;
end;
end;
procedure DObject.DoCancel (modifiers: integer; ch: char; code: integer);
begin
if cancel_item = 0 then
DoKey(modifiers, ch, code)
else begin
FlashItem(window, cancel_Item);
DoItem(cancel_item);
end;
end;
procedure DObject.DoItem (item: integer);
begin
end;
procedure DObject.DoItemWhere (er: eventRecord; item: integer);
begin
DoItem(item);
end;
function DObject.HandleEvents (er: eventRecord): boolean;
var
b: boolean;
ch: char;
begin
b := true;
if ((er.what = KeyDown) or (er.what = AutoKey)) then begin
b := false;
ch := chr(BAND(er.message, charCodeMask));
if (ch = chr(13)) or (ch = chr(3)) then
DoOK(er.modifiers, ch, BAND(er.message, keyCodeMask) div $100)
else if (ch = chr(27)) or ((ch = '.') and (BAND(er.modifiers, cmdKey) <> 0)) then
DoCancel(er.modifiers, ch, BAND(er.message, keyCodeMask) div $100)
else
b := true;
end;
if b then
b := inherited HandleEvents(er);
HandleEvents := b;
end;
procedure DTObject.SetEditMenuItem (item: integer);
begin
TESetEditMenuItem(dialogPeek(window)^.textH, false, 250, item);
end;
function DTObject.EditMenuEnabled: boolean;
begin
EditMenuEnabled := TEEditMenuEnabled(dialogPeek(window)^.textH, false, 250);
end;
procedure DTObject.DoEditMenu (item: integer);
var
modified: boolean;
begin
modified := TEDoEditMenu(dialogPeek(window)^.textH, false, 250, item);
end;
function DTObject.DoIsDialogEvent (er: eventRecord): boolean;
begin
if ((er.what = keyDown) or (er.what = autoKey)) and (BAND(er.modifiers, cmdKey) <> 0) then begin
DoIsDialogEvent := false; { Stop system 7 from doing the edit menu as well }
end
else
DoIsDialogEvent := inherited DoIsDialogevent(er);
end;
end.